Skip to content

Tighten geotiff reader: partial-tile validation, ModelTransformation rotation guard#1491

Merged
brendancol merged 1 commit into
mainfrom
issue-1486
May 5, 2026
Merged

Tighten geotiff reader: partial-tile validation, ModelTransformation rotation guard#1491
brendancol merged 1 commit into
mainfrom
issue-1486

Conversation

@brendancol

Copy link
Copy Markdown
Contributor

Closes #1486.

Summary

Two accuracy fixes in xrspatial/geotiff/.

_decode_strip_or_tile now validates the decompressed byte count against the expected size before reshape. A truncated deflate stream used to surface as cannot reshape array of size N into shape (h, w) with no hint of which tile or what was expected. New error names the tile geometry, expected size, actual size, and points at corruption.

_extract_transform now checks ModelTransformationTag (34264) for non-zero rotation (M[1], M[4]) and z-coupling (M[2], M[6]) and raises NotImplementedError. The old code used only the diagonal terms and silently produced a corrupted GeoTransform on rotated rasters.

The audit also flagged a possible MinIsWhite + windowed-read issue. On close reading the window is clamped to image bounds before allocating output, so padding never reaches the inversion. Skipped with a note in the issue.

Test plan

  • test_truncated_tile_raises_clear_error - corrupt deflate stream raises ValueError with the size mismatch
  • test_valid_edge_tile_still_works - 9x9 image with 4x4 tiles round-trips cleanly (edge tiles are partial)
  • test_axis_aligned_extracts_correctly - ModelTransformationTag without rotation extracts origin/pixel sizes
  • test_rotation_raises - non-zero M[1]/M[4] raises NotImplementedError
  • test_z_coupling_raises - non-zero M[2]/M[6] raises NotImplementedError
  • Full geotiff suite: 478 passed (was 473), 3 pre-existing matplotlib RecursionError failures unrelated to this PR

… rotation guard (#1486)

Two accuracy fixes in the geotiff read path:

1. Validate decompressed tile/strip byte count in `_decode_strip_or_tile`
   before the reshape. A truncated deflate stream or a misbehaving
   compressor previously triggered an opaque "cannot reshape array of
   size N" message; now it raises ValueError with the expected size,
   actual size, and tile geometry. Edge tiles in valid TIFFs continue
   to decompress to the full tile_height x tile_width and pass the
   check unchanged.

2. Detect rotation, skew, and z-coupling in ModelTransformationTag
   (34264) and raise NotImplementedError. The previous code silently
   used only the diagonal terms, returning a corrupted GeoTransform
   for rotated rasters with no warning to the caller. Axis-aligned
   matrices keep working.

Notes the audit also flagged a possible MinIsWhite + windowed-read
issue, but the windowing path clamps to image bounds before allocating
the output, so no padding ever reaches the inversion. Skipped.

Adds 5 tests covering corrupt-tile detection, valid-edge-tile pass-through,
axis-aligned ModelTransformation extraction, and the two error paths.
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 5, 2026
@brendancol brendancol merged commit a70a773 into main May 5, 2026
11 checks passed
@brendancol brendancol deleted the issue-1486 branch May 15, 2026 04:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tighten geotiff accuracy: partial-tile validation, ModelTransformationTag rotation

1 participant